/*
 * Copyright 2024 ywcai
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

`include "./core/defines.v"
`timescale 1ns/1ps

module riscv_top(
	input	wire			clk,
	input	wire			rst_n,
	input	wire[`IrqBus]	irq_i
	);

	wire					pp_en;

	wire					m0_req;
	wire					m0_we;
	wire[`MemAddrBus]		m0_addr;
	wire[`CacheBus]	    	m0_wr_data;
	wire[`CacheBus]			m0_rd_data;
	wire[`CACHE_BITS/8-1:0]	m0_strb;
	wire[11:0]				m0_pulse_bits;
	wire[1:0]				m0_errcode;
	wire					transact_done;

	reg[`IrqBus]        	irq;

    wire                	s0_we_o;
	wire[`MemAddrBus]		s0_addr_o;
	wire[`RegDataBus]		s0_wr_data_o;
	wire[7:0]				s0_strb_o;
	wire[`RegDataBus]		s0_rd_data_o;
	wire[1:0]				s0_errcode_i;
    wire                	s1_we_o = `DISABLE;
	wire[`MemAddrBus]		s1_addr_o;
	wire[`RegDataBus]		s1_wr_data_o;
	wire[7:0]				s1_strb_o;
	wire[`RegDataBus]		s1_rd_data;
	wire[1:0]				s1_errcode;
    wire                	s2_we_o;
	wire[`MemAddrBus]		s2_addr_o;
	wire[`RegDataBus]		s2_wr_data_o;
	wire[7:0]				s2_strb_o;
	wire[`RegDataBus]		s2_rd_data_o;
	wire[1:0]				s2_errcode_i;
    wire                	s3_we_o;
	wire[`MemAddrBus]		s3_addr_o;
	wire[`RegDataBus]		s3_wr_data_o;
	wire[7:0]				s3_strb_o;
	wire[`RegDataBus]		s3_rd_data_o;
	wire[1:0]				s3_errcode_i;
    wire                	s4_we_o;
	wire[`MemAddrBus]		s4_addr_o;
	wire[`RegDataBus]		s4_wr_data_o;
	wire[7:0]				s4_strb_o;
	wire[`RegDataBus]		s4_rd_data_i;
	wire[1:0]				s4_errcode_i;
    wire                	s5_we_o;
	wire[`MemAddrBus]		s5_addr_o;
	wire[`RegDataBus]		s5_wr_data_o;
	wire[7:0]				s5_strb_o;
	wire[`RegDataBus]		s5_rd_data_o;
	wire[1:0]				s5_errcode_i;
    wire                	s6_we_o;
	wire[`MemAddrBus]		s6_addr_o;
	wire[`RegDataBus]		s6_wr_data_o;
	wire[7:0]				s6_strb_o;
	wire[`RegDataBus]		s6_rd_data_o;
	wire[1:0]				s6_errcode_i;
    wire                	s7_we_o;
	wire[`MemAddrBus]		s7_addr_o;
	wire[`RegDataBus]		s7_wr_data_o;
	wire[7:0]				s7_strb_o;
	wire[`RegDataBus]		s7_rd_data_o;
	wire[1:0]				s7_errcode_i;

	core i_core(
		.clk(clk),
		.rst_n(rst_n),
		.mem_rd_data_i(m0_rd_data),
		.transact_done_i(transact_done),
		.irq_i(irq),
		.pp_en_o(pp_en),
		.mem_req_o(m0_req),
		.mem_we_o(m0_we),
		.mem_addr_o(m0_addr),
		.mem_wr_data_o(m0_wr_data),
		.mem_strb_o(m0_strb),
		.mem_pulse_bits_o(m0_pulse_bits)
	);

	rom i_rom(
		.clk(clk),
		.rst_n(rst_n),
		.pc_i(s1_addr_o),
		.inst_o(s1_rd_data),
		.errcode_o(s1_errcode)
	);

	ram i_ram(
		.clk(clk),
		.rst_n(rst_n),
        .we_i(s4_we_o),
		.addr_i(s4_addr_o),
		.wr_data_i(s4_wr_data_o),
		.strb_i(s4_strb_o),
		.rd_data_o(s4_rd_data_i),
		.errcode_o(s4_errcode_i)
	);

	bus_ctrl i_bus_ctrl(
		.clk(clk),
		.rst_n(rst_n),
		.m0_req_i(m0_req),
		.m0_we_i(m0_we),
		.m0_addr_i(m0_addr),
		.m0_wr_data_i(m0_wr_data),
		.m0_strb_i(m0_strb),
		.m0_pulse_bits_i(m0_pulse_bits),
		.m1_req_i(1'b0),
		.m1_we_i(),
		.m1_addr_i(),
		.m1_wr_data_i(),
		.m1_strb_i(),
		.m1_pulse_bits_i(),
		.m2_req_i(1'b0),
		.m2_we_i(),
		.m2_addr_i(),
		.m2_wr_data_i(),
		.m2_strb_i(),
		.m2_pulse_bits_i(),
		.m3_req_i(1'b0),
		.m3_we_i(),
		.m3_addr_i(),
		.m3_wr_data_i(),
		.m3_strb_i(),
		.m3_pulse_bits_i(),
		.s0_rd_data_i(),
        .s0_errcode_i(),
		.s1_rd_data_i(s1_rd_data),
		.s1_errcode_i(s1_errcode),
		.s2_rd_data_i(),
        .s2_errcode_i(),
		.s3_rd_data_i(),
        .s3_errcode_i(),
		.s4_rd_data_i(s4_rd_data_i),
		.s4_errcode_i(s4_errcode_i),
		.s5_rd_data_i(),
        .s5_errcode_i(),
		.s6_rd_data_i(),
        .s6_errcode_i(),
		.s7_rd_data_i(),
        .s7_errcode_i(),
		.m0_rd_data_o(m0_rd_data),
		.m0_errcode_o(m0_errcode),
		.m1_rd_data_o(),
		.m1_errcode_o(),
		.m2_rd_data_o(),
		.m2_errcode_o(),
		.m3_rd_data_o(),
		.m3_errcode_o(),
        .s0_we_o(),
		.s0_addr_o(),
		.s0_wr_data_o(),
		.s0_strb_o(),
        .s1_we_o(s1_we_o),
		.s1_addr_o(s1_addr_o),
		.s1_wr_data_o(),
		.s1_strb_o(),
        .s2_we_o(),
		.s2_addr_o(),
		.s2_wr_data_o(),
		.s2_strb_o(),
        .s3_we_o(),
		.s3_addr_o(),
		.s3_wr_data_o(),
		.s3_strb_o(),
        .s4_we_o(s4_we_o),
		.s4_addr_o(s4_addr_o),
		.s4_wr_data_o(s4_wr_data_o),
		.s4_strb_o(s4_strb_o),
        .s5_we_o(),
		.s5_addr_o(),
		.s5_wr_data_o(),
		.s5_strb_o(),
        .s6_we_o(),
		.s6_addr_o(),
		.s6_wr_data_o(),
		.s6_strb_o(),
        .s7_we_o(),
		.s7_addr_o(),
		.s7_wr_data_o(),
		.s7_strb_o(),
		.req_result_o(),
		.transact_done_o(transact_done)
	);

	always @(posedge rst_n) begin
		if (rst_n == `RESET_ENABLE) begin
			irq <= `IRQ_NONE;
        end else begin
            irq <= irq_i;
        end
	end

endmodule

